#ifndef __KEY_MANAGEMENT_H__
#define __KEY_MANAGEMENT_H__

#include <stdint.h>
#include <openssl/ec.h>

typedef struct {
    uint32_t uuid;
    uint8_t *pin;               // 伪PIN码
    uint8_t *bd_addr;           // 绑定的蓝牙设备地址,长度18B
    uint32_t start_time;        // 伪PIN码生效的开始时间
    uint32_t end_time;          // 伪PIN码有效的结束时间
    uint32_t expiration_time;   // 使用伪PIN码建立的连接的过期时间
    uint8_t flag;               // 0x01管理员， 0x00普通权限
} PIN;

typedef struct {
    uint32_t uuid;
    EC_KEY *eckey_mobile;       // 移动终端的公钥
    EC_KEY *eckey_car;          // 车载蓝牙的公钥
    uint8_t *secret;            // 对称加密密钥
    uint32_t expiration_time;   // uuid 的过期时间
    uint32_t recent_request;    // 最近的一次请求时间戳
    uint8_t flag;               // 0x01管理员， 0x00普通权限
} KEY;


/**
 * 判断uid建立的连接是否具有管理员权限
 * @return 1：管理员权限 0：普通权限
 */
int isAdmin(uint32_t uuid);

/**
 * 判断uid建立的连接是否有效
 * @return 1：有效 0：无效
 */
int keyIsValid(KEY *key);

/**
 * 判断uid对应的伪PIN码是否在有效期内
 * @return 1：有效 0：无效
 */
int pinIsValid(PIN *pin);

/**
 * 根据时间戳判断当前请求是否有效
 * @param time 时间戳 
 * @return 1：有效 0：无效
 */
int requestIsValid(KEY *key, uint32_t time);

/**
 * 更新请求的最新时间戳
 * @param time 时间戳 
 */
void updateRequestTime(KEY *key, uint32_t time);

/**
 * 获取非对称加密密钥对
 * @param owner 通过该参数指定获取密钥对的目标，0x00移动终端 0x01车载蓝牙
 */
EC_KEY* getEC_Key(uint32_t uuid, uint8_t owner);

/**
 * 保存非对称加密密钥对
 * @param eckey 非对称密钥对
 * @param owner 通过该参数指定保存的密钥对所属目标，0x00移动终端 0x01车载蓝牙
 */
int saveEC_Key(uint32_t uuid, EC_KEY* eckey, uint8_t owner);

/**
 * 将KEY对象保存到密钥管理容器中
 */
int setKEY(KEY *key);

/**
 * 根据uid获取到其对应的KEY对象
 */
KEY* getKey(uint32_t uuid);

/**
 * 通过伪PIN码生成token
 */
uint8_t* getToken(uint8_t *pin);

/**
 * 通过伪PIN码生成uid
 */
uint32_t getUid(uint8_t* pin);

/**
 * 保存uid此次连接的对称密钥，同时更新uid对应的最新时间戳
 * @param secret 对称密钥的指针
 */
void setSecretAndUpdateTime(uint32_t uuid, uint8_t *secret);

/**
 * 获取uid的对称密钥
 */
uint8_t* getSecret(uint32_t uuid);

/**
 * 根据uid获取到对应的PIN对象
 */
PIN* getPIN(uint32_t uuid);

/**
 * 保存PIN对象到密钥管理容器中
 * @return 0：成功 非0：失败
 */
int setPIN(PIN *pin);

/**
 * 销毁伪PIN码
 */
int destroyPIN(uint32_t uuid);

#endif